package com.atom.test.opengl

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.PixelFormat
import android.opengl.GLES30
import android.os.Bundle
import android.util.Log
import android.view.Choreographer
import android.view.SurfaceHolder
import android.view.SurfaceView
import androidx.appcompat.app.AppCompatActivity
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import com.atom.module.lib.opengles.draw.GlCircle
import com.atom.module.lib.opengles.egl.EGLHelper
import com.atom.module.lib.opengles.egl.EGLWrapper
import com.atom.module.lib.opengles.shader.GlScene
import com.atom.module.lib.opengles.shader.GlSimpleProgram
import com.atom.module.logger.Logger
import com.blankj.utilcode.util.LogUtils

class FrameCallbackActivity : AppCompatActivity() , Choreographer.FrameCallback {

    private lateinit var surfaceView: SurfaceView
    private lateinit var wrapper: EGLWrapper
    private var flatProgram: GlSimpleProgram? = null

    private val scene = GlScene()
    private val circle = GlCircle()

    private val drawAnimator = ValueAnimator.ofFloat(0F, 1F).also {
        it.repeatCount = ValueAnimator.INFINITE
        it.repeatMode = ValueAnimator.REVERSE
        it.duration = 1200
        it.interpolator = FastOutSlowInInterpolator()
        it.addUpdateListener { draw() }
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        surfaceView = SurfaceView(this)
        surfaceView.setZOrderOnTop(true)
        surfaceView.holder.setFormat(PixelFormat.RGBA_8888)
        surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(holder: SurfaceHolder) {
                Log.e("SHAPES", "CREATED." + Thread.currentThread().name)
                onSurfaceCreated(holder)
            }

            override fun surfaceChanged(
                holder: SurfaceHolder,
                format: Int,
                width: Int,
                height: Int
            ) {

            }

            override fun surfaceDestroyed(holder: SurfaceHolder) {
                onSurfaceDestroyed()
            }
        })
        setContentView(surfaceView)
    }

    private fun onSurfaceCreated(holder: SurfaceHolder) {
        wrapper = EGLHelper.initDisplay()
        wrapper.createGLESWithSurface(surface = holder.surface!!)
        flatProgram = GlSimpleProgram()
        drawAnimator.start()
    }

    private fun onSurfaceDestroyed() {
        drawAnimator.cancel()
        flatProgram?.release()
        flatProgram = null

        wrapper.release()
    }

    private fun draw() {
        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT)
        // Draw the circle.
        flatProgram!!.setColor(Color.RED)
        circle.radius = 0.5f
        scene.draw(flatProgram!!, circle)
        // Publish.
        wrapper.swapBuffers()
    }

    override fun onDestroy() {
        onSurfaceDestroyed()
        super.onDestroy()
    }

    override fun doFrame(frameTimeNanos: Long) {
        Logger.e("FrameCallbackActivity" )
        Choreographer.getInstance().postFrameCallback(this)
    }

    override fun onPause() {
        super.onPause()
        Choreographer.getInstance().removeFrameCallback(this)
    }

    override fun onResume() {
        super.onResume()
        Choreographer.getInstance().postFrameCallback(this)
    }
}